import java.util.regex.*;
import java.util.*;
import java.io.*;

/**
 * Tests voor opdracht 3.2 van TI1310 Datastructuren en Algoritmen.
 *
 * Gijs van Tulder, 15.02.2011
 */
public class TestOpdracht32 {
  /**
   * Runs the tests.
   */
  public static void main(String[] args) {
    runTest("", "");
    runTest("a", "a");
    runTest("ab", "ab, ba");
    runTest("abc", "abc, acb, bac, bca, cab, cba");
    runTest("abcd", "abcd, abdc, acbd, acdb, adbc, adcb, bacd,"+
                    "badc, bcad, bcda, bdac, bdca, cabd, cadb,"+
                    "cbad, cbda, cdab, cdba, dabc, dacb, dbac,"+
                    "dbca, dcab, dcba");
  }


  /**
   * Matches groups of letters/numbers.
   */
  private static final Pattern tokens = Pattern.compile("[a-z0-9]+");

  /**
   * Extracts the groups of letters/numbers from str
   * and discards the non-interesting characters (whitespace etc.).
   * Returns a set of tokens.
   */
  private static Set<String> parseString(String str) {
    Set<String> set = new TreeSet<String>();
    Matcher match = tokens.matcher(str);
    
    // extract the interesting tokens (numbers and letters)
    // and add them to the set
    while (match.find()) {
      set.add(match.group());
    }

    return set;
  }

  /**
   * Checks if all items in expectedString also occur in
   * actualString. (Order insensitive.)
   * Prints the result of this test.
   */
  private static void check(String expectedString, String actualString) {
    Set<String> expected = parseString(expectedString);
    Set<String> actual   = parseString(actualString);

    if (expected.equals(actual)) {
      // exactly the same contents
      System.out.println(" success.");

    } else {
      // there is a difference
      System.out.println(" FAILED.");
      System.out.println(" Expected:  "+expected);
      System.out.println(" Actual:    "+actual);

      // expected - actual
      Set<String> missing = new TreeSet<String>(expected);
      missing.removeAll(actual);
      System.out.println(" Missing:   "+missing);

      // actual - expected
      Set<String> extra = new TreeSet<String>(actual);
      extra.removeAll(expected);
      System.out.println(" Incorrect: "+extra);

      System.out.println();
    }
  }

  /**
   * Runs a test of SchrijfPermutaties with the given s.
   * Compares the result with the contents of expected.
   */
  private static void runTest(String s, String expected) {
    System.out.printf("%-41s", "SchrijfPermutaties(\""+s+"\");  ");

    // remember the real output stream
    PrintStream outReal = System.out;

    // the output is redirected to here
    ByteArrayOutputStream capture = new ByteArrayOutputStream();

    try {
      // redirect output
      System.setOut(new PrintStream(capture));

      // execute test
      Opdracht32.SchrijfPermutaties(s);
    }
    finally {
      // restore standard output stream
      System.setOut(outReal);
    }

    // collect output
    String output = capture.toString();

    // compare and print result
    check(expected, output);
  }
}

